#pragma once

// Disable warnings about invalid XML
#pragma warning(disable:4635)
#include <Awesomium/ResourceInterceptor.h>
#pragma warning(default:4635)

#include "vcclr.h"

using namespace System;

namespace AwesomiumDotNet
{
	class ResourceInterceptorWrapper;
	ref struct ResourceResponseMetrics;
	ref class WebView;
	ref class ResourceRequest;

	/// <summary>
	/// The ResourceResponse class is simply a wrapper around a raw block of data and
	/// a specified mime-type. It can be used with ResourceInterceptor.OnRequest
	/// to return a custom resource for a certain resource request.
	/// </summary>
	public ref class ResourceResponse
	{
	private:
		Awesomium::ResourceResponse* _response;
		ResourceResponse();
		ResourceResponse(Awesomium::ResourceResponse* response);

	internal:
		Awesomium::ResourceResponse* getNative();

	public:
		/// <summary>
		/// Create a ResourceResponse from a raw block of data. (Data is not owned,
	    /// a copy is made of the supplied buffer.)
		/// </summary>
		/// <param name="buffer">
		/// Raw memory buffer to be copied.
		/// </param>
		/// <param name="mimeType">
		/// The mime-type of the data.
	    /// See http://en.wikipedia.org/wiki/Internet_media_type
		/// </param>
		static ResourceResponse^ Create(array<Byte>^ buffer, String^ mimeType);

		/// <summary>
		/// Create a ResourceResponse from a file on disk.
		/// </summary>
		/// <param name="filePath">
		/// The path to the file.
		/// </param>
		static ResourceResponse^ Create(String^ filePath);

		ResourceResponse(array<Byte>^ buffer, String^ mimeType);
		ResourceResponse(String^ filePath);
	};

	/// <summary>
	/// The ResourceRequest class represents a request for a URL resource. You can
	/// get information about the request or modify it (change GET to POST, modify
	/// headers, etc.).
	/// </summary>
	public ref class ResourceRequest
	{
	private:
		Awesomium::ResourceRequest* _request;

	internal:
		ResourceRequest(Awesomium::ResourceRequest* request);
	};

	/// <summary>
	/// The ResourceInterceptor class is used to intercept requests and responses 
	/// for resources via WebView.ResourceInterceptor. This can be used for
	/// responding to resource requests using your own custom resource loading
	/// scheme or for tracking resource loads.
	/// </summary>
	public ref class ResourceInterceptor
	{
	private:
		ResourceInterceptorWrapper* resourceInterceptor;

	protected:
		ResourceInterceptor();

	public:
		/// <summary>
		/// Override this method to intercept requests for resources. You can use 
		/// this to modify requests before they are sent, respond to requests using 
		/// your own custom resource-loading back-end, or to monitor requests for 
		/// tracking purposes.
		/// </summary>
		/// <param name="caller">
		/// The WebView instance that invoked the request.
		/// </param>
		/// <param name="request">
		/// The resource request.
		/// </param>
		/// <returns>
		/// Return a new ResourceResponse (see ResourceResponse.Create)
		/// to override the response, otherwise, return null to allow
		/// normal behavior.
		/// </returns>
		virtual ResourceResponse^ OnRequest(WebView^ caller, ResourceRequest^ request);

		/// <summary>
		/// Override this method to intercept responses to requests. You can use
		/// this for tracking/statistics purposes.
		/// </summary>
		/// <param name="caller">
		/// The WebView instance that invoked the response.
		/// </param>
		/// <param name="url">
		/// The URL of the response.
		/// </param>
		/// <param name="statusCode">
		/// The HTTP status code of the response. For non-HTTP responses,
		/// 200 represents "success" and 404 represents "failure".
		/// </param>
		/// <param name="metrics">
		/// Various informative metrics about the response.
		/// </param>
		virtual void OnResponse(WebView^ caller, String^ url, int statusCode, ResourceResponseMetrics^ metrics);

	internal:
		ResourceInterceptorWrapper* getNative();
	};

	class ResourceInterceptorWrapper : public Awesomium::ResourceInterceptor
	{
	private:
		gcroot<AwesomiumDotNet::ResourceInterceptor^> _resourceInterceptor;
		gcroot<WebView^> _owner;

	public:
		void setOwner(WebView^ owner);

	public:
		ResourceInterceptorWrapper(AwesomiumDotNet::ResourceInterceptor^ resourceInterceptor);

		Awesomium::ResourceResponse* onRequest(Awesomium::WebView* caller, Awesomium::ResourceRequest* request);
		void onResponse(Awesomium::WebView* caller, const std::string& url, int statusCode, const Awesomium::ResourceResponseMetrics& metrics);
	};

	/// <summary>
	/// Various informative statistics about a certain resource response.
	/// </summary>
	public ref struct ResourceResponseMetrics
	{
	public:
		/// <summary>
		/// Whether or not the resource was cached
		/// </summary>
		bool wasCached;

		/// <summary>
		/// The time of the request, in milliseconds
		/// </summary>
		int64 requestTimeMs;

		/// <summary>
		/// The time that the response began, in milliseconds
		/// </summary>
		int64 responseTimeMs;

		/// <summary>
		/// The expected content size given by the server
		/// </summary>
		int64 expectedContentSize;

		/// <summary>
		/// The mime-type of the response
		/// </summary>
		String^ mimeType;

	internal:
		ResourceResponseMetrics(const Awesomium::ResourceResponseMetrics& metrics);
	};
};
